package com.dm.cloud.controller;

import com.dm.cloud.common.R;
import com.dm.cloud.databases.redis.RedissionUtils;
import com.dm.cloud.service.ITestService;
import com.dm.cloud.service.ITransService;
import com.dm.cloud.utils.CodeFormater;
import com.dm.cloud.utils.minio.MinioUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.util.Strings;
import org.redisson.RedissonMultiLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

@Log4j2
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    ITestService testService;

    @Autowired
    ITransService transService;

    @GetMapping("/getTest")
    public void getTest(){
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String pwd = encoder.encode("nacos");
        System.out.println(pwd);
    }

    /**
     * 异步
     * @return
     */
    @GetMapping("async")
    public void async(HttpServletRequest request, HttpServletResponse response){

        //开启异步
        AsyncContext asyncContext =request.startAsync();
        CompletableFuture.runAsync(()-> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                response.getWriter().append("nihao");
            } catch (IOException e) {
                e.printStackTrace();
            }
            asyncContext.complete();
        });
    }

    @GetMapping("/redistrylock")
    public int search(){

        IntStream.rangeClosed(1,6).parallel().boxed().forEach(
                e->{
                    try {
                        log.info(String.format(" 线程 %s，加锁结果 %s", Thread.currentThread().getName(), testService.redisLock()));
                    }catch (Exception ex){
                        log.error(ex.getMessage());
                    }
                });
        return 0;
    }


    @GetMapping("/redissionlock")
    public int redissionlock(){

        IntStream.rangeClosed(1,6).parallel().boxed().forEach(
            e->{
                RedissionUtils redissionUtils = RedissionUtils.getInstance();

                RedissonMultiLock redissonMultiLock = redissionUtils.getRedissonMultiLock(redissionUtils.getRedisson("redis://127.0.0.1","6379"),"test1","test2","test3");

                redissonMultiLock.lock(3,TimeUnit.SECONDS);

                System.out.println(e+" get lock");

            });
        return 0;
    }

    @GetMapping("/zklock")
    public int zklock(){

//        testService.zkLock();

        IntStream.rangeClosed(1,6).parallel().boxed().forEach(
                e->{
                    try {
                        testService.zkLock(e);
                    }catch (Exception ex){
                        log.error(ex.getMessage());
                    }
                });
        return 0;
    }

    @GetMapping("/delzknode")
    public int delzknode(){

        return 0;
    }

    @GetMapping("/Db/{db}")
    public R<Object> search(@PathVariable("db") String db){
        R<Object> o= testService.multiDbTest("","",db);
        log.info("database [{}] tables {}",db,o.getResult());
        return o;
    }

    @PostMapping("/minio/uploud")
    public R<Object> uploud(@RequestParam("file") MultipartFile file) {

        try {
            return R.success(MinioUtils.upload(file.getInputStream(),file.getContentType()));
        }catch (Exception ex){
            log.error("解析失败");
            return R.failure("",ex.getMessage());
        }
    }

    @GetMapping("/minio/download")
    public R<Object> uploud(@RequestParam(value = "minioLoc",required = false) String minioLoc, @RequestParam("bucket") String bucket, @RequestParam("fileName") String fileName) {
        try {

            Map<String,String> sd =new HashMap<>();
            if(Strings.isNotBlank(minioLoc))
                sd.put("minioLoc",minioLoc);
            sd.put("bucket",bucket);
            sd.put("fileName",fileName);

            return R.success(CodeFormater.getBase64FromInputStream(MinioUtils.getMinio(sd).body().byteStream()));
        }catch (Exception ex){
            log.error("解析失败");
            return R.failure("",ex.getMessage());
        }
    }

    @GetMapping("/transaction/test")
    public void transactionTest() {
        transService.transTerst();
    }
}
